/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.secretaria.saude.negocio.base.impl;

import com.secretaria.saude.negocio.base.DefaultService;
import java.io.Serializable;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import org.hibernate.Session;

/**
 *
 * @author pablo
 */
public abstract class DefaultServiceImpl<T, K extends Serializable> implements DefaultService<T, K> {

    private Class clazz;
    
    protected EntityManager entityManager;

    public DefaultServiceImpl(EntityManager entityManager, Class clazz) {
       this.entityManager = entityManager;
       this.clazz = clazz;
    } 

    public <T> T persist(T t) {
        beginTransaction();
        entityManager.persist(t);
        commit();
        
        return t;
    }

    public <T> T update(T t) {
        beginTransaction();
        entityManager.merge(t);
        commit();
        return t;
    }

    public <T, PK extends Serializable> void delete(Class<T> type, PK id) {
        T ref = (T) entityManager.find(type, id);
        beginTransaction();
        entityManager.remove(ref);
        commit();

    }
    
    public <T, PK extends Serializable> void delete( PK id) {
        T entity = (T) entityManager.find(clazz, id);
        beginTransaction();
        entityManager.remove(entity);
        commit();
    }
    
    public void delete(T ref) {
        beginTransaction();
        entityManager.remove(ref);
        commit();

    }

    public <T, PK extends Serializable> T find( PK id) {
            return (T) entityManager.find(clazz, id);
    }

    public void refresh(T object) {
        entityManager.refresh(object);
    }
    
    public List<T> findAll() {
        String queryString = " FROM " + clazz.getSimpleName();
        Query query = entityManager.createQuery(queryString);
        return query.getResultList();
    }

    /**
     * Implementação especifica do hibernate para remover um objeto
     * da HibernateSession
     * 
     */
    public void discard(T object) {
        Session session = (Session) entityManager.getDelegate();
        session.evict(object);
    }

    public void beginTransaction() {
        if(!entityManager.getTransaction().isActive()) {
            entityManager.getTransaction().begin();
        }
    }

    public void rollback() {
        entityManager.getTransaction().rollback();
    }

    public void commit() {

        entityManager.getTransaction().commit();
    }

    public T attach(T object) {
        beginTransaction();
        entityManager.merge(object);
        commit();
        return object;
    }
}
